﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System;
using System.Threading;
using System.ComponentModel;
using BrainTechLLC.ThreadSafeObjects;
using System.Runtime.Serialization;

namespace BrainTechLLC
{
    public class RequestAllItemTemplates : ByteDataMessage, ICanCustomSerialize, IRegisterAsSerializable
    {
        public RequestAllItemTemplates() { Bytes = new byte[4]; ByteCount = 4; }
        public override int TransmissionType { get { return (int)TransmissionEnum.RequestAllItemTemplates; } }
    }

    public class RequestAllItems : ByteDataMessage, ICanCustomSerialize, IRegisterAsSerializable
    {
        public RequestAllItems() { Bytes = new byte[4]; ByteCount = 4; }
        public override int TransmissionType { get { return (int)TransmissionEnum.RequestAllItems; } }
    }

    public class RequestAllAreas : ByteDataMessage, ICanCustomSerialize, IRegisterAsSerializable
    {
        public RequestAllAreas() { Bytes = new byte[4]; ByteCount = 4; }
        public override int TransmissionType { get { return (int)TransmissionEnum.RequestAllAreas; } }
    }

    public class RequestAllGameCharTemplates : ByteDataMessage, ICanCustomSerialize, IRegisterAsSerializable
    {
        public RequestAllGameCharTemplates() { Bytes = new byte[4]; ByteCount = 4; }
        public override int TransmissionType { get { return (int)TransmissionEnum.RequestAllGameCharTemplates; } }
    }

    public class RequestAllGameChars : ByteDataMessage, ICanCustomSerialize, IRegisterAsSerializable
    {
        public RequestAllGameChars() { Bytes = new byte[4]; ByteCount = 4; }
        public override int TransmissionType { get { return (int)TransmissionEnum.RequestAllGameChars; } }
    }

    public class RequestAllGameLocations : ByteDataMessage, ICanCustomSerialize, IRegisterAsSerializable
    {
        public RequestAllGameLocations() { Bytes = new byte[4]; ByteCount = 4; }
        public override int TransmissionType { get { return (int)TransmissionEnum.RequestAllLocations; } }
    }

    public class RequestAllResets : ByteDataMessage, ICanCustomSerialize, IRegisterAsSerializable
    {
        public RequestAllResets() { Bytes = new byte[4]; ByteCount = 4; }
        public override int TransmissionType { get { return (int)TransmissionEnum.RequestAllResets; } }
    }

    public class RequestObjectById : ByteDataMessage, ICanCustomSerialize, IRegisterAsSerializable
    {
        public RequestObjectById() { Bytes = new byte[4]; ByteCount = 4; }
        public override int TransmissionType { get { return (int)TransmissionEnum.RequestObjectById; } }
    }

    public class RequestAllLocationEdges : ByteDataMessage, ICanCustomSerialize, IRegisterAsSerializable
    {
        public RequestAllLocationEdges() { Bytes = new byte[4]; ByteCount = 4; }
        public override int TransmissionType { get { return (int)TransmissionEnum.RequestAllLocationEdges; } }
    }

    [DataContract]
    public class ByteDataMessage : ICanCustomSerialize, IRegisterAsSerializable
    {
        [DataMember]
        public int ByteCount { get; set; }

        [DataMember]
        public long ID { get; set; }

        [DataMember]
        public byte[] Bytes { get; set; }

        public virtual int SerializeOut(BinaryWriter b)
        {
            b.Write(ByteCount);
            b.Write(Bytes);
            b.Write(ID);
            return 12 + Bytes.Length;
        }

        public virtual int SerializeIn(object o, BinaryReader b)
        {
            ByteDataMessage msg = o as ByteDataMessage;
            msg.ByteCount = b.ReadInt32();
            msg.Bytes = b.ReadBytes(msg.ByteCount);
            msg.ID = b.ReadInt64();
            return 12 + msg.ByteCount;
        }

        public virtual int TransmissionType { get { return (int)TransmissionEnum.RawByteData; } }

        public static void Register()
        {
            ((int)TransmissionEnum.RawByteData).RegisterType(typeof(ByteDataMessage));
            ((int)TransmissionEnum.RequestAllGameChars).RegisterType(typeof(RequestAllGameChars));
            ((int)TransmissionEnum.RequestAllGameCharTemplates).RegisterType(typeof(RequestAllGameCharTemplates));
            ((int)TransmissionEnum.RequestAllLocations).RegisterType(typeof(RequestAllGameLocations));
            ((int)TransmissionEnum.RequestAllItems).RegisterType(typeof(RequestAllItems));
            ((int)TransmissionEnum.RequestAllItemTemplates).RegisterType(typeof(RequestAllItemTemplates));
            ((int)TransmissionEnum.RequestAllAreas).RegisterType(typeof(RequestAllAreas));
            ((int)TransmissionEnum.RequestAllResets).RegisterType(typeof(RequestAllResets));
            ((int)TransmissionEnum.RequestObjectById).RegisterType(typeof(RequestObjectById));
            ((int)TransmissionEnum.RequestAllLocationEdges).RegisterType(typeof(RequestAllLocationEdges));
        }
    }

    [DataContract]
    public class NumericMessage : ICanCustomSerialize, IRegisterAsSerializable
    {
        [DataMember]
        public int Numeric { get; set; }

        public virtual int SerializeOut(BinaryWriter b)
        {
            b.Write(Numeric);
            return 4;
        }

        public virtual int SerializeIn(object o, BinaryReader b)
        {
            NumericMessage msg = o as NumericMessage;
            msg.Numeric = b.ReadInt32();
            return 4;
        }

        public virtual int TransmissionType { get { return (int)TransmissionEnum.RequestUniqueId; } }

        public static void Register()
        {
            ((int)TransmissionEnum.RequestUniqueId).RegisterType(typeof(NumericMessage));
            ((int)TransmissionEnum.RespondUniqueId).RegisterType(typeof(NumericMessage));
        }
    }

    [DataContract]
    public class StringMessage : ICanCustomSerialize, IRegisterAsSerializable
    {
        [DataMember]
        public string String1 { get; set; }

        [DataMember]
        public string String2 { get; set; }

        [DataMember]
        public string String3 { get; set; }

        [DataMember]
        public long ID { get; set; }

        public virtual int SerializeOut(BinaryWriter b)
        {
            b.Write(ID);
            b.Write(String1);
            b.Write(String2);
            b.Write(String3);
            return 16;
        }

        public virtual int SerializeIn(object o, BinaryReader b)
        {
            StringMessage msg = o as StringMessage;
            msg.ID = b.ReadInt64();
            msg.String1 = b.ReadString();
            msg.String2 = b.ReadString();
            msg.String3 = b.ReadString();
            return 16;
        }

        public virtual int TransmissionType { get { return (int)TransmissionEnum.StringMessage; } }

        public static void Register()
        {
            ((int)TransmissionEnum.StringMessage).RegisterType(typeof(StringMessage));            
        }
    }

    [DataContract]
    public class NumericMessageDouble : ICanCustomSerialize, IRegisterAsSerializable
    {
        [DataMember]
        public double Numeric { get; set; }

        public virtual int SerializeOut(BinaryWriter b)
        {
            b.Write(Numeric);
            return 8;
        }

        public virtual int SerializeIn(object o, BinaryReader b)
        {
            NumericMessageDouble msg = o as NumericMessageDouble;
            msg.Numeric = b.ReadInt32();
            return 8;
        }

        public virtual int TransmissionType { get { return (int)TransmissionEnum.NumericMessageDouble; } }

        public static void Register()
        {
            ((int)TransmissionEnum.NumericMessageDouble).RegisterType(typeof(NumericMessageDouble));
        }
    }

    [DataContract]
    public class StringAndNumeric : NumericMessage, ICanCustomSerialize, IRegisterAsSerializable
    {
        [DataMember]
        public string Text { get; set; }

        public override int SerializeOut(BinaryWriter b)
        {
            int bytes = base.SerializeOut(b);
            b.Write(Text);
            return Text.Length + bytes;
        }

        public override int SerializeIn(object o, BinaryReader b)
        {
            StringAndNumeric msg = o as StringAndNumeric;
            int bytes = base.SerializeIn(o, b);
            msg.Text = b.ReadString();
            return msg.Text.Length + bytes;
        }

        public override int TransmissionType { get { return (int)TransmissionEnum.StringAndNumeric; } }

        public new static void Register()
        {
            ((int)TransmissionEnum.StringAndNumeric).RegisterType(typeof(StringAndNumeric));
        }
    }

    [DataContract]
    public class TwoStringsAndTwoNumerics : NumericMessageDouble, ICanCustomSerialize, IRegisterAsSerializable
    {
        [DataMember]
        public string Text1 { get; set; }

        [DataMember]
        public string Text2 { get; set; }

        [DataMember]
        public double Numeric2 { get; set; }

        public override int SerializeOut(BinaryWriter b)
        {
            int bytes = base.SerializeOut(b);
            b.Write(Text1);
            b.Write(Text2);
            b.Write(Numeric2);
            return Text1.Length + Text2.Length + 8 + bytes;
        }

        public override int SerializeIn(object o, BinaryReader b)
        {
            TwoStringsAndTwoNumerics msg = o as TwoStringsAndTwoNumerics;
            int bytes = base.SerializeIn(o, b);
            msg.Text1 = b.ReadString();
            msg.Text2 = b.ReadString();
            Numeric2 = b.ReadDouble();
            return msg.Text1.Length + msg.Text2.Length + 8 + bytes;
        }

        public override int TransmissionType { get { return (int)TransmissionEnum.TwoStringsAndTwoNumerics; } }

        public new static void Register()
        {
            ((int)TransmissionEnum.TwoStringsAndTwoNumerics).RegisterType(typeof(TwoStringsAndTwoNumerics));
        }
    }
}
